package zero.tech.games.extension.queue;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Configuration;

import com.alibaba.fastjson.JSONObject;

import zero.tech.core.util.DatetimeUtil;
import zero.tech.games.common.ClubRoleId;
import zero.tech.games.common.ClubWater;
import zero.tech.games.common.QueueConsts;
import zero.tech.games.common.RedisConsts;
import zero.tech.games.common.ThreadRunner;
import zero.tech.games.entity.games.ClubMemberProxy;
import zero.tech.games.entity.games.ClubMemberRole;
import zero.tech.games.entity.games.ClubMemberWaterSummery;
import zero.tech.games.entity.games.ClubMemberWaterpak;
import zero.tech.games.entity.log.LogWaterOwn;
import zero.tech.games.entity.log.LogWaterTeam;
import zero.tech.games.extension.mapper.ClubMemberProxyMapper;
import zero.tech.games.extension.mapper.ClubMemberRoleMapper;
import zero.tech.games.extension.mapper.ClubMemberWaterSummeryMapper;
import zero.tech.games.extension.mapper.ClubMemberWaterpakMapper;
import zero.tech.games.extension.runner.ServerInitProcess;
import zero.tech.games.extension.service.api.IExtensionService;
import zero.tech.redis.cache.RedisUtil;
import zero.tech.redis.queue.QueueUtil;
@Configuration
@AutoConfigureAfter(ServerInitProcess.class)
public class ClubWaterProcess extends ThreadRunner{
	private static final Logger logger=LoggerFactory.getLogger(ClubWaterProcess.class);
	@Autowired
	private QueueUtil queueUtil;
	@Autowired
	private ClubMemberWaterSummeryMapper clubMemberWaterSummeryMapper;
	@Autowired
	private ClubMemberProxyMapper clubMemberProxyMapper;
	@Autowired
	private ClubMemberRoleMapper clubMemberRoleMapper;
	@Autowired
	private ClubMemberWaterpakMapper clubMemberWaterpakMapper;
	@Autowired
	private IExtensionService extensionService;
	@Autowired
	private RedisUtil redisUtil;
	@Override
	public void process() {
		while(true) {
			int sleep = 0;
			List<String> list = queueUtil.pullQueueBatch(QueueConsts.QUEUE_CLUB_WATER, 100);
			try {
				if (list == null || list.isEmpty()) {
					sleep = 1000;
				} else {
					// 开始处理业务
					long time = System.currentTimeMillis();
					logger.info("============================开始流水日志入库==============================");
					
					List<ClubWater> clubWaters=new ArrayList<ClubWater>();
					for(String str:list) {
						ClubWater clubWater = JSONObject.parseObject(str,ClubWater.class);
						clubWaters.add(clubWater);
					}
					if(!clubWaters.isEmpty()) {
						calculateWaters(clubWaters);
					}
					logger.info("=====================结束流水日志入库,操作耗时:{}毫秒========================",
							(System.currentTimeMillis() - time));
				}
			} catch (Exception e) {
				e.printStackTrace();
				sleep = 1000;
			}
			if (sleep != 0) {
				try {
					Thread.sleep(sleep);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}		
	}
	private void calculateWaters(List<ClubWater> clubWaters) {
		List<LogWaterOwn> logWaterOwns=new ArrayList<>();
		List<LogWaterTeam> logWaterTeams=new ArrayList<>();
		List<ClubMemberWaterSummery>inserts=new ArrayList<>();
		List<ClubMemberWaterpak> clubMemberWaterpaks=new ArrayList<>();
		for(ClubWater clubWater:clubWaters) {
			int uid=clubWater.getUid();
			int club_id=clubWater.getClub_id();
			int game_id=clubWater.getGame_id();
			String room_id=clubWater.getRoom_id();
			int rule_id=clubWater.getRule_id();
			long water=clubWater.getWater();
			if(water>0) {
				Date now=clubWater.getNow();
				String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
				logWaterOwns.add(packageLogWaterOwn(clubWater));
				
				//插入
				ClubMemberWaterSummery own=new ClubMemberWaterSummery();
				own.setClub_id(club_id);
				own.setUid(uid);
				own.setWater_own(water);
				own.setWater_zs(0L);
				own.setWater_fzs(0L);
				own.setWater_zs_effect(0L);
				own.setWater_fzs_effect(0L);
				own.setDay_str(day_str);
				own.setCreate_stamp(now);
				inserts.add(own);
				
				List<Integer> fathers=extensionService.getParentIds(club_id, uid);
				ClubMemberRole clubMemberRole = getClubMemberRole(club_id, uid);
				if(clubMemberRole.getRole()!=ClubRoleId.NOMAL) {
					//打的业绩算自己的直属业绩,算上级的团队业绩
					long effect=calZsEffect(club_id,uid,water);
					logWaterTeams.add(packageLogWaterTeam(club_id,uid,uid,1,water,effect,now,game_id,room_id,rule_id));
					ClubMemberWaterSummery waterSummery=new ClubMemberWaterSummery();
					waterSummery.setClub_id(club_id);
					waterSummery.setUid(uid);
					waterSummery.setWater_own(0L);
					waterSummery.setWater_zs(water);
					waterSummery.setWater_fzs(0l);
					waterSummery.setWater_zs_effect(effect);
					waterSummery.setWater_fzs_effect(0l);
					waterSummery.setDay_str(day_str);
					waterSummery.setCreate_stamp(now);
					inserts.add(waterSummery);
					clubMemberWaterpaks.add(packageClubMemberWaterpak(club_id,uid,waterSummery.getWater_zs_effect(),waterSummery.getWater_fzs_effect()));
					//算上级的团队业绩
					if(!fathers.isEmpty()) {
						for(int i=0;i<fathers.size();i++) {
							int father_uid=fathers.get(i);
							if(i==0) {
								effect=calFzsEffect(club_id,uid,father_uid,water);
							}else {
								int index=fathers.indexOf(father_uid);
								if(index!=-1&&index>=1) {
									Integer pre_father_uid=fathers.get(index-1);
									if(pre_father_uid!=null) {
										effect=calFzsEffect(club_id,pre_father_uid,father_uid,water);
									}
								}
							}
							logWaterTeams.add(packageLogWaterTeam(club_id,uid,father_uid,0,water,effect,now,game_id,room_id,rule_id));
							ClubMemberWaterSummery waterSummery1=new ClubMemberWaterSummery();
							waterSummery1.setClub_id(club_id);
							waterSummery1.setUid(father_uid);
							waterSummery1.setWater_own(0L);
							waterSummery1.setWater_zs(0l);
							waterSummery1.setWater_fzs(water);
							waterSummery1.setWater_zs_effect(0l);
							waterSummery1.setWater_fzs_effect(effect);
							waterSummery1.setDay_str(day_str);
							waterSummery1.setCreate_stamp(now);
							inserts.add(waterSummery1);
							clubMemberWaterpaks.add(packageClubMemberWaterpak(club_id,father_uid,waterSummery1.getWater_zs_effect(),waterSummery1.getWater_fzs_effect()));
						}
					}
				}else {
					//打的业绩算直属上级的直属业绩,算上上级的团队业绩
					if(!fathers.isEmpty()) {
						int zs_father=fathers.get(0);
						for(int father_uid:fathers) {
							int direct=father_uid==zs_father?1:0;
							long effect=0;
							if(direct==1) {
								effect=calZsEffect(club_id, father_uid, water);
							}else {
								int index=fathers.indexOf(father_uid);
								if(index!=-1&&index>=1) {
									Integer pre_father_uid=fathers.get(index-1);
									if(pre_father_uid!=null) {
										effect= calFzsEffect(club_id,pre_father_uid,father_uid,water);
									}
								}
							}
							logWaterTeams.add(packageLogWaterTeam(club_id,uid,father_uid,direct,water,effect,now,game_id,room_id,rule_id));
							ClubMemberWaterSummery waterSummery1=new ClubMemberWaterSummery();
							waterSummery1.setClub_id(club_id);
							waterSummery1.setUid(father_uid);
							waterSummery1.setWater_own(0L);
							waterSummery1.setWater_zs(direct==1?water:0);
							waterSummery1.setWater_fzs(direct==1?0:water);
							waterSummery1.setWater_zs_effect(direct==1?effect:0);
							waterSummery1.setWater_fzs_effect(direct==0?effect:0);
							waterSummery1.setDay_str(day_str);
							waterSummery1.setCreate_stamp(now);
							inserts.add(waterSummery1);
							clubMemberWaterpaks.add(packageClubMemberWaterpak(club_id,father_uid,waterSummery1.getWater_zs_effect(),waterSummery1.getWater_fzs_effect()));
						}
					}
				}
				
			}
		}
		if(!inserts.isEmpty()) {
			clubMemberWaterSummeryMapper.insertOrUpadateBatch(inserts);
		}
		if(!inserts.isEmpty()) {
			clubMemberWaterpakMapper.insertOrUpadateBatch(inserts);
		}
		
		if(!logWaterOwns.isEmpty()) {
			queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_WATER_OWN, logWaterOwns);
		}
		if(!logWaterTeams.isEmpty()) {
			queueUtil.putQueueBatch(QueueConsts.QUEUE_LOG_WATER_TEAM, logWaterTeams);
		}
	}
	private LogWaterTeam packageLogWaterTeam(int club_id, int uid, int father_uid, int direct, long water,long water_effect, Date now, int game_id, String room_id, int rule_id) {
		String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", now);
		LogWaterTeam logWaterTeam = new LogWaterTeam();
		logWaterTeam.setClub_id(club_id);
		logWaterTeam.setUid(father_uid);
		logWaterTeam.setOther_uid(uid);
		logWaterTeam.setDirect(direct);
		logWaterTeam.setWater(water);
		logWaterTeam.setWater_effect(water_effect);
		logWaterTeam.setDay_str(day_str);
		logWaterTeam.setCreate_stamp(now);
		logWaterTeam.setGame_id(game_id);
		logWaterTeam.setRoom_id(room_id);
		logWaterTeam.setRule_id(rule_id);
		return logWaterTeam;
	}
	private LogWaterOwn packageLogWaterOwn(ClubWater clubWater) {
		String day_str=DatetimeUtil.parseDateToString("yyyy-MM-dd", clubWater.getNow());
		LogWaterOwn logWaterOwn = new LogWaterOwn();
		logWaterOwn.setClub_id(clubWater.getClub_id());
		logWaterOwn.setUid(clubWater.getUid());
		logWaterOwn.setDay_str(day_str);
		logWaterOwn.setCreate_stamp(clubWater.getNow());
		logWaterOwn.setGame_id(clubWater.getGame_id());
		logWaterOwn.setRoom_id(clubWater.getRoom_id());
		logWaterOwn.setRule_id(clubWater.getRule_id());
		return logWaterOwn;
	}
	private ClubMemberWaterpak packageClubMemberWaterpak(int club_id, int uid, Long water_zs_effect, Long water_fzs_effect) {
		ClubMemberWaterpak clubMemberWaterpak = new ClubMemberWaterpak();
		clubMemberWaterpak.setClub_id(club_id);
		clubMemberWaterpak.setUid(uid);
		clubMemberWaterpak.setWater_zs_effect(water_zs_effect);
		clubMemberWaterpak.setWater_fzs_effect(water_fzs_effect);
		return clubMemberWaterpak;
	}
	private long calFzsEffect(int club_id, Integer pre_uid, int father_uid, long water) {
		long effect=0;
		ClubMemberProxy preClubMemberProxy=getClubMemberProxy(club_id, pre_uid);
		ClubMemberProxy clubMemberProxy= getClubMemberProxy(club_id, father_uid);
		if(preClubMemberProxy!=null&&clubMemberProxy!=null) {
			float fanyong1=clubMemberProxy.getFanyong();
			float fanyong2=preClubMemberProxy.getFanyong();
			BigDecimal b1=new BigDecimal(fanyong1);
			BigDecimal b2=new BigDecimal(fanyong2);
			BigDecimal cha=(b1.subtract(b2)).multiply(new BigDecimal(water));
			cha=cha.setScale(2, RoundingMode.UP);
			if(cha.longValue()>0) {
				effect=cha.longValue();
			}
		}
		return effect;
	}

	private long calZsEffect(int club_id, int uid, long water) {
		long effect=0;
		ClubMemberProxy clubMemberProxy=getClubMemberProxy(club_id, uid);
		if(clubMemberProxy!=null) {
			float fanyong=clubMemberProxy.getFanyong();
			if(fanyong>0) {
				effect=(long) (water*fanyong);
			}
		}
		return effect;
	}
	
	public ClubMemberProxy getClubMemberProxy(int club_id, int uid) {
		ClubMemberProxy clubMemberProxy=(ClubMemberProxy) redisUtil.hget(RedisConsts.HOT_CLUBMEMBER_PROXY+"_"+club_id, String.valueOf(uid));
		if(clubMemberProxy==null) {
			clubMemberProxy=clubMemberProxyMapper.getClubMemberProxy(club_id,uid);
			if(clubMemberProxy!=null) {
				redisUtil.hset(RedisConsts.HOT_CLUBMEMBER_PROXY+"_"+club_id, String.valueOf(uid), clubMemberProxy, 30*60);
			}
		}
		return clubMemberProxy;
	}
	
	public ClubMemberRole getClubMemberRole(int club_id, int uid) {
		ClubMemberRole clubMemberRole=(ClubMemberRole) redisUtil.hget(RedisConsts.HOT_CLUBMEMBER_ROLE+"_"+club_id, String.valueOf(uid));
		if(clubMemberRole==null) {
			clubMemberRole=clubMemberRoleMapper.getClubMemberRole(club_id,uid);
			if(clubMemberRole!=null) {
				redisUtil.hset(RedisConsts.HOT_CLUBMEMBER_ROLE+"_"+club_id, String.valueOf(uid), clubMemberRole, 30*60);
			}
		}
		return clubMemberRole;
	}
	
}
